﻿using System;
using System.CodeDom.Compiler;
using System.Text;
using System.Collections.ObjectModel;

namespace Ooaavee.Scripting
{
    /// <summary>
    /// The exception that is thrown when failed to compile a script.
    /// </summary>
    public sealed class ScriptCompileException : Exception
    {
        private readonly Collection<ErrorMessage> _errorMessages = new Collection<ErrorMessage>();

        /// <summary>
        /// The programming language.
        /// </summary>
        public Language Language { private set; get; }

        /// <summary>
        /// The full source code.
        /// </summary>
        public string FullSourceCode { private set; get; }

        /// <summary>
        /// Error messages.
        /// </summary>
        public Collection<ErrorMessage> ErrorMessages { get { return _errorMessages; } }

        internal ScriptCompileException(CompilerErrorCollection errors, Language language, string fullSourceCode) : base(GetCompilerErrors(errors))
        {
            Language = language;
            FullSourceCode = fullSourceCode;

            foreach (CompilerError error in errors)
            {
                if (error.IsWarning == false)
                {           
                    ErrorMessages.Add(new ErrorMessage { ErrorNumber =  error.ErrorNumber, ErrorText = error.ErrorText } );
                }
            }
        }

        private static string GetCompilerErrors(CompilerErrorCollection errors)
        {
            StringBuilder s = new StringBuilder();
            foreach (CompilerError error in errors)
            {
                if (error.IsWarning == false)
                {
                    if (s.Length > 0)
                    {
                        s.AppendLine(Environment.NewLine);
                    }
                    s.Append(string.Format("error {0}: {1}", error.ErrorNumber, error.ErrorText));
                }
            }
            return s.ToString();
        }


        public struct ErrorMessage
        {
            public string ErrorNumber;
            public string ErrorText;
        }
    }
}